/**
* verbatim extract from Prelude.srule of what is used in FingerList,
* but renamed List -> cons */

private unwrapInt(integer(i)) is i;
private ZERO is unwrapInt(0);
private ONE is unwrapInt(1);
  
array_foldRight has type ((%a, %b) => %b, %b, array of %a) => %b;
array_foldRight(f, a, arr) is valof {
  var res := a;
  var r := arr;
  var sz := __array_size(arr);
  var i := __integer_minus(sz, ONE);
  while __integer_ge(i, ZERO) do {
    res := f(__array_element(arr, i), res);
    i := __integer_minus(i, ONE);
  }
  valis res;
};

array_foldLeft has type ((%b, %a) => %b, %b, array of %a) => %b;
array_foldLeft(f, a, arr) is valof {
  var res := a;
  var r := arr;
  var i := ZERO;
  var sz := __array_size(arr);
  while __integer_ne(i, sz) do {
    res := f(res, __array_element(arr, i));
    i := __integer_plus(i, ONE);
  }
  valis res;
};

array_int_foldLeft has type ((_integer,%a)=>_integer,_integer,array of %a)=>_integer;
array_int_foldLeft(f, a, arr) is valof {
  var res := a;
  var r := arr;
  var i := ZERO;
  var sz := __array_size(arr);
  while __integer_ne(i, sz) do {
    res := f(res, __array_element(arr, i));
    i := __integer_plus(i, ONE);
  }
  valis res;
};

array_mapcar has type ((%a) => %b, array of %a) => array of %b;
array_mapcar(f, arr) is valof {
  var res := __array_nil();
  var i := ZERO;
  var sz := __array_size(arr);
  while not(__integer_ge(i, sz)) do { -- i < sz
    res := __array_append(res, f(__array_element(arr, i)));
    i := __integer_plus(i, ONE);
  }
  valis res;
};

